import * as THREE from "three";
import { SimulatorBase } from "./SimulatorBase";
import { SimulationFrameVector } from "./SimulationFrameVector";
import { springV } from "../../core/FunctionLibrary";

export class VectorSpringSimulator extends SimulatorBase {

	public position: THREE.Vector3;
	public velocity: THREE.Vector3;
	public target: THREE.Vector3;
	public cache: SimulationFrameVector[];

	constructor ( fps: number, mass: number, damping: number ) {

		super( fps, mass, damping );

		this.init();

	}

	public init (): void {

		this.position = new THREE.Vector3();
		this.velocity = new THREE.Vector3();
		this.target = new THREE.Vector3();

		this.cache = [];

		for ( let i = 0; i < 2; i++ ) {

			this.cache.push(
				new SimulationFrameVector( new THREE.Vector3(), new THREE.Vector3() )
			);

		}

	}

	/**
	 * 通过给定的时间步长进行模拟
	 * @param {number} timeStep 
	 */
	simulate ( timeStep: number ): void {

		this.generateFrames( timeStep );

		const cache0 = this.cache[ 0 ];
		const cache1 = this.cache[ 1 ];
		const alpha = this.offset / this.frameTime;

		this.position.lerpVectors( cache0.position, cache1.position, alpha );
		this.velocity.lerpVectors( cache0.velocity, cache1.velocity, alpha );

	}

	public getFrame ( isLastFrame: boolean ): SimulationFrameVector {

		const lastFrame = this.laseFrame() as SimulationFrameVector;
		const newSpring = new SimulationFrameVector( lastFrame.position.clone(), lastFrame.velocity.clone() );
		springV( newSpring.position, this.target, newSpring.velocity, this.mass, this.damping );

		return newSpring;
	}
}